import {
  Button,
  Text,
  TextInput,
  View,
  TouchableOpacity,
  StyleSheet,
  ScrollView,
} from "react-native";
import dayjs from "dayjs";
import { useEffect, useRef, useState } from "react";
import Spinner from "react-native-loading-spinner-overlay";
import {
  WritableWithResponse,
  determineCurrentDevice,
  getStorageData,
  setStorageData,
  stringToGBKHex,
} from "utils";
import { manager } from "utils/bleManage";
import toast from "utils/toast";
import { useAppSelector } from "app/store";
import translate from "utils/translate";
export default ({
  navigation,
  route: { params },
}: RootStackScreenProps<"addManage">) => {
  type FormKeys = keyof Omit<typeof params, "index">;
  const connectedDevice = useAppSelector((state) => {
    return state.app.connectedDevice;
  });
  const manageList = useRef<Omit<typeof params, "index">[]>([]);
  const [loading, setLoading] = useState(false);
  const handleChange = (value: string, key: FormKeys) => {
    setForm((prevForm) => ({
      ...prevForm,
      [key]: value,
    }));
  };
  const handleSave = async () => {
    if (!form.remark) {
      return toast(translate("main.labelError"));
    }
    for (let p of List) {
      if (
        (form[p.prop as FormKeys]?.replaceAll(/[\u4e00-\u9fa5]/g, "aa")
          ?.length ?? 0) > (p.maxLength ?? 0)
      ) {
        return toast(translate("main.tooLong"));
      }
    }
    const storageData = await getStorageData("manageList");
    const bleList = storageData ? JSON.parse(storageData) : [];

    if (params.index === 0 || params.index) {
      bleList.splice(params.index, 1, form);
    } else {
      bleList.unshift(form);
    }

    await setStorageData("manageList", JSON.stringify(bleList));
    navigation.goBack();
  };
  const ondel = async () => {
    const storageData = await getStorageData("manageList");
    const bleList = storageData ? JSON.parse(storageData) : [];
    bleList.splice(params.index, 1);
    await setStorageData("manageList", JSON.stringify(bleList));
    navigation.goBack();
  };
  const onSync = async (type: string, prop?: FormKeys) => {
    if (
      prop &&
      (form[prop]?.replaceAll(/[\u4e00-\u9fa5]/g, "aa")?.length ?? 0) >
        (List.find((item) => item.label === type)?.maxLength ?? 0)
    ) {
      return toast(translate("main.tooLong"));
    }
    if (params.index === 0 || params.index) {
      if (type !== translate("manage.time") && !form[prop as FormKeys])
        return toast(translate("main.labelError"));
      if (connectedDevice) {
        setLoading(true);
        const services = await manager
          .discoverAllServicesAndCharacteristicsForDevice(connectedDevice)
          .then((device) => {
            return device.services();
          })
          .catch(() => {
            return toast(translate("main.error"));
          });
        if (services) {
          const item = determineCurrentDevice(services);
          if (item) {
            const characteristicsList = await item.characteristics();
            for (let current of characteristicsList) {
              if (current.isWritableWithResponse && current.isNotifiable) {
                if (type === translate("manage.time")) {
                  const hexValue = stringToGBKHex(
                    dayjs().format("YYdMMDDHHmmss")
                  );
                  const currentTime = (hexValue + "0D0A").substring(0, 40);
                  try {
                    await WritableWithResponse(current, "AA");
                    await WritableWithResponse(current, "01");
                    await WritableWithResponse(current, currentTime);
                    await WritableWithResponse(current, "0F");
                    toast(translate("main.success"));
                    setLoading(false);
                  } catch {
                    setLoading(false);
                    return toast(translate("main.error"));
                  }
                } else if (type === translate("manage.shopName")) {
                  const hexValue = stringToGBKHex(form.shopName ?? "");
                  const currentValue = hexValue + "0D0A";
                  try {
                    await WritableWithResponse(current, "AA");
                    await WritableWithResponse(current, "02");
                    if (currentValue.length > 40) {
                      await WritableWithResponse(
                        current,
                        currentValue.substring(0, 40)
                      );
                      await WritableWithResponse(
                        current,
                        currentValue.substring(40, currentValue.length)
                      );
                    } else {
                      await WritableWithResponse(current, currentValue);
                    }
                    await WritableWithResponse(current, "0F");
                    toast(translate("main.success"));
                    onSave();
                    setLoading(false);
                  } catch {
                    setLoading(false);
                    return toast(translate("main.error"));
                  }
                } else if (type === translate("manage.phone")) {
                  const hexValue = stringToGBKHex(form.phone ?? "");
                  const currentValue = hexValue + "0D0A";
                  try {
                    await WritableWithResponse(current, "AA");
                    await WritableWithResponse(current, "04");
                    await WritableWithResponse(current, currentValue);
                    await WritableWithResponse(current, "0F");
                    onSave();
                    toast(translate("main.success"));
                    setLoading(false);
                  } catch {
                    setLoading(false);
                    return toast(translate("main.error"));
                  }
                } else {
                  const hexValue = stringToGBKHex(form.address ?? "");
                  const currentValue = hexValue + "0D0A";
                  try {
                    await WritableWithResponse(current, "AA");
                    await WritableWithResponse(current, "05");
                    if (currentValue.length > 40) {
                      await WritableWithResponse(
                        current,
                        currentValue.substring(0, 40)
                      );
                      await WritableWithResponse(
                        current,
                        currentValue.substring(40, currentValue.length)
                      );
                    } else {
                      await WritableWithResponse(current, currentValue);
                    }
                    await WritableWithResponse(current, "0F");
                    onSave();
                    toast(translate("main.success"));
                    setLoading(false);
                  } catch {
                    setLoading(false);
                    return toast(translate("main.error"));
                  }
                }
                return;
              }
            }
          } else {
            setLoading(false);
            return toast(translate("main.error"));
          }
        }
      } else {
        toast(translate("main.connectTip"));
      }
    } else {
      toast(translate("main.informationTip"));
    }
  };
  const onSave = () => {
    manageList.current.splice(params.index as number, 1, form);
    setStorageData("manageList", JSON.stringify(manageList.current));
  };
  const [form, setForm] = useState<Partial<Omit<typeof params, "index">>>({});
  const List: {
    prop?: FormKeys;
    label: string;
    placeholder?: string;
    maxLength?: number;
    multiline?: boolean;
    numberOfLines?: number;
    keyboardType?: "numeric";
  }[] = [
    {
      label: translate("manage.remark"),
      prop: "remark",
      placeholder: translate("main.toCmplete"),
      maxLength: 20,
    },
    {
      label: translate("manage.shopName"),
      prop: "shopName",
      placeholder: translate("main.toCmplete"),
      multiline: true,
      numberOfLines: 2,
      maxLength: 20,
    },
    {
      label: translate("manage.phone"),
      prop: "phone",
      placeholder: translate("main.toCmplete"),
      keyboardType: "numeric",
      maxLength: 15,
    },
    {
      label: translate("manage.address"),
      prop: "address",
      placeholder: translate("main.toCmplete"),
      multiline: true,
      numberOfLines: 2,
      maxLength: 30,
    },
    {
      label: translate("manage.time"),
    },
  ];
  let [currentTime, setCurrentTime] = useState(
    dayjs().format("YYYY.MM.DD HH:mm:ss")
  );

  useEffect(() => {
    getStorageData("manageList").then((value) => {
      manageList.current = value ? JSON.parse(value) : [];
    });
    setForm(() => {
      const { index, ...rest } = params;
      return {
        ...rest,
      };
    });
    const timer = setInterval(() => {
      setCurrentTime(dayjs().format("YYYY.MM.DD HH:mm:ss"));
    }, 1000);
    return () => {
      clearInterval(timer);
    };
  }, []);
  return (
    <View style={{ flex: 1, backgroundColor: "#fff", alignItems: "center" }}>
      <Spinner
        visible={loading}
        textContent={translate("main.loading") + "..."}
        textStyle={{
          color: "rgba(10, 89, 247, .8)",
        }}
        color="rgba(10, 89, 247, .8)"
        cancelable
      />
      <ScrollView style={{ flex: 1, padding: 20 }}>
        {List.map((item) => {
          return (
            <View
              key={item.label}
              style={{
                flexDirection: "row",
                alignItems: "center",
                marginBottom: 10,
                justifyContent: "space-evenly",
                width: "100%",
              }}
            >
              <View style={{ flex: 1 }}>
                <Text>{item.label}</Text>
              </View>
              <View
                style={{
                  flexDirection: "row",
                  alignItems: "center",
                  borderWidth: 1,
                  borderRadius: 8,
                  marginLeft: 10,
                  marginRight: 10,
                  borderColor: "#ccc",
                  padding: 8,
                  width: 190,
                  justifyContent: "space-between",
                }}
              >
                <TextInput
                  onChangeText={(value) => {
                    handleChange(value, item.prop as FormKeys);
                  }}
                  defaultValue={
                    !item.prop ? currentTime : form[item.prop as FormKeys]
                  }
                  style={{
                    flex: 5,
                  }}
                  keyboardType={item.keyboardType}
                  multiline={item.multiline}
                  numberOfLines={item.numberOfLines}
                  placeholder={item.placeholder}
                  editable={!item.prop ? false : true}
                ></TextInput>
                {item.prop && (
                  <Text style={{ flex: 1, minWidth: 10, marginLeft: 5 }}>
                    {form[item.prop as FormKeys]?.replaceAll(
                      /[\u4e00-\u9fa5]/g,
                      "aa"
                    )?.length ?? 0}
                    /{item.maxLength}
                  </Text>
                )}
              </View>

              {
                <View
                  style={{
                    flex: 1,
                    opacity: item.prop === "remark" ? 0 : 1,
                  }}
                >
                  <Button
                    onPress={() => {
                      if (item.prop === "remark") return;
                      onSync(item.label, item.prop);
                    }}
                    title={translate("class.Sync")}
                  ></Button>
                </View>
              }
            </View>
          );
        })}
        <TouchableOpacity style={styles.button} onPress={handleSave}>
          <Text
            style={{
              textAlign: "center",
              color: "#fff",
            }}
          >
            {translate("main.Submit")}
          </Text>
        </TouchableOpacity>
        {params.remark && (
          <TouchableOpacity
            style={{ ...styles.button, backgroundColor: "#ff0000" }}
            onPress={ondel}
          >
            <Text
              style={{
                textAlign: "center",
                color: "#fff",
              }}
            >
              {translate("main.delete")}
            </Text>
          </TouchableOpacity>
        )}
      </ScrollView>
    </View>
  );
};
const styles = StyleSheet.create({
  button: {
    backgroundColor: "#0A59F7",
    width: "80%",
    height: 50,
    marginBottom: 30,
    borderRadius: 16,
    alignItems: "center",
    justifyContent: "center",
    alignSelf: "center",
  },
});
